package com.dana1.nos.old.util;

import java.io.PrintStream;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.collections.keyvalue.MultiKey;

public class HardMemoizer 
{
	private static final Map<MultiKey, Object> byDomains = new HashMap<MultiKey, Object>();
	private static PrintStream debugStream = null;
	
	@SuppressWarnings("unchecked")
	public static <T> T memoize(Producer<T> producer, Object ... keys)
	{
		T result = null;
		MultiKey key = new MultiKey(keys);
		if (debugStream!=null)
			producer = new DebuggingProducer<T>(producer,key);
		synchronized (byDomains)
		{
			if (byDomains.containsKey(key))
				result = (T)byDomains.get(key);
			else
				byDomains.put(key,result = producer.produce());
		}
		return result;
	}
	
	public static void printKeySet(PrintStream out)
	{
		for (MultiKey k: byDomains.keySet())
			System.out.println(k);
	}

	public static void setDebugStream(PrintStream out)
	{
		debugStream = out;
	}
	
	private static class DebuggingProducer<T> implements Producer<T>
	{
		Producer<T> producer;
		MultiKey key;
		private DebuggingProducer(Producer<T> producer,MultiKey key)
		{
			this.producer = producer;
			this.key = key;
		}
		@Override
		public T produce()
		{
			debugStream.println("[HardMemoizer] Adding: "+key);
			return producer.produce();
		}
	}
}
